﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;

namespace PayloadTracker
{

    public class Logger
    {
        public static Logger LOG = new Logger(Settings.Default["LogPath"] as string);


        System.IO.TextWriter m_MainLog, m_ErrorLog, m_APRSLog, m_FlightLog;
        System.IO.BinaryWriter m_SampleLog;
        bool m_Enabled;

        private Logger(string path)
        {


            try
            {
                if (!System.IO.Directory.Exists(path))
                    System.IO.Directory.CreateDirectory(path);

                string filebase = Path.Combine(path, DateTime.Now.Ticks.ToString() + "_");


                m_MainLog = new StreamWriter(System.IO.File.Open(filebase + "main.log", FileMode.Create, FileAccess.Write, FileShare.Read));
                m_ErrorLog = new StreamWriter(System.IO.File.Open(filebase + "error.log", FileMode.Create, FileAccess.Write, FileShare.Read));
                m_APRSLog = new StreamWriter(System.IO.File.Open(filebase + "aprs.log", FileMode.Create, FileAccess.Write, FileShare.Read));
                m_FlightLog = new StreamWriter(System.IO.File.Open(filebase + "flight.log", FileMode.Create, FileAccess.Write, FileShare.Read));
                m_SampleLog = new BinaryWriter(System.IO.File.Open(filebase + "audio.log.bin", FileMode.Create, FileAccess.Write, FileShare.Read));
                m_Enabled = true;
            }
            catch (System.Exception ex)
            {
                m_Enabled = false;
                Warn("Error creating log files. Data will NOT be logged!");
                WriteLine("Unable to create log files. Will log to debugger ONLY. \r\n" + ex.ToString(),false);
            }

        }

        public void Warn(string s)
        {
            Warn(s, false);
        }

        public void Warn(string s, bool log)
        {
            System.Windows.Forms.MessageBox.Show(s, "Warning", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Warning);
            if (log)
                Error(s);
        }

        public void Error(string s)
        {
            Error(s, false);
        }

        public void Error(string s, bool show)
        {
            string es = "ERROR: " + s;
            
            WriteLine(es,false);

            if (!m_Enabled)
                return;

            m_ErrorLog.Write(DateTime.Now + ": " + s);
            m_ErrorLog.Flush();

            if (show)
            {
                System.Windows.Forms.MessageBox.Show(s, "Error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Warning);
            }
        }

        public void AudioSample(float f)
        {
            m_SampleLog.Write(f);
            m_SampleLog.Flush();
        }

        public void APRSBeacon(APRS.APRSBeacon b, Flight f)
        {
            if (!m_Enabled)
                return;

            if (f != null)
            {
                string s = f.Callsign + ": " + b.ToString();
                WriteLine(s,true);
                m_FlightLog.WriteLine(DateTime.Now + ": " + s);
                m_FlightLog.Flush();
            }
            m_APRSLog.WriteLine(DateTime.Now + ": " + b.ToString());
            m_APRSLog.Flush();
        }

        public void Write(string message)
        {
            System.Diagnostics.Debug.Write(message);

            if (!m_Enabled)
                return;
            
            m_MainLog.Write(message);
            m_MainLog.Flush();
        }

        private void WriteLine(string message, bool silent)
        {
            if(!silent)
                System.Diagnostics.Debug.WriteLine(message);

            if (!m_Enabled)
                return;

            m_MainLog.WriteLine(DateTime.Now + ": " + message);
            m_MainLog.Flush();
        }
        public void WriteLine(string message)
        {
            WriteLine(message,false);
        }
    }
}
